package main

import (
    "encoding/json"
    "fmt"
    "encoding/xml"
    "io/ioutil"
    "github.com/vmihailenco/msgpack"
    "math/rand"
)

type Person struct {
    Name  string `json:"-"`
    Hobby string `json:"hobby" `
}

type Person2 struct {
    Age       int    `json:"age,string"`
    Name      string `json:"name"`
    Niubility bool   `json:"niubility"`
}

// 抽取单个server对象
type Server struct {
    ServerName string `xml:"serverName"`
    ServerIP   string `xml:"serverIP"`
 }
 
 type Servers struct {
    XMLName xml.Name `xml:"servers"`
    Version int   `xml:"version,attr"`
    Servers []Server `xml:"server"`
 }

 type Person3 struct {
    Name string
    Age  int
    Sex  string
 }
 
 // 二进制写出
 func writerJson(filename string) (err error) {
    var persons []*Person3
    // 假数据
    for i := 0; i < 10; i++ {
       p := &Person3{
          Name: fmt.Sprintf("name%d", i),
          Age:  rand.Intn(100),
          Sex:  "male",
       }
       persons = append(persons, p)
    }
    // 二进制json序列化
    data, err := msgpack.Marshal(persons)
    if err != nil {
       fmt.Println(err)
       return
    }
    err = ioutil.WriteFile(filename, data, 0666)
    if err != nil {
       fmt.Println(err)
       return
    }
    return
 }
 
 // 二进制读取
 func readJson(filename string) (err error) {
    var persons []*Person3
    // 读文件
    data, err := ioutil.ReadFile(filename)
    if err != nil {
       fmt.Println(err)
       return
    }
    // 反序列化
    err = msgpack.Unmarshal(data, &persons)
    if err != nil {
       fmt.Println(err)
       return
    }
    for _, v := range persons {
       fmt.Printf("%#v\n", v)
    }
    return
 }

func main() {
    p := Person{"5lmh.com", "女"}
    // 编码json
    b, err := json.Marshal(p)
    if err != nil {
        fmt.Println("json err ", err)
    }
    fmt.Println(string(b))

    // 格式化输出
    b, err = json.MarshalIndent(p, "", "    ")
    if err != nil {
        fmt.Println("json err ", err)
    }
    fmt.Println(string(b))

    student := make(map[string]interface{})
    student["name"] = "5lmh.com"
    student["age"] = 18
    student["sex"] = "man"
    b1, err := json.Marshal(student)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(string(b1))

    // 假数据
    b2 := []byte(`{"age":"18","name":"5lmh.com","marry":false}`)
    var p2 Person2
    err2 := json.Unmarshal(b2, &p2)
    if err2 != nil {
        fmt.Println(err2)
    }
    fmt.Println(p2)
    fmt.Printf("%#v\n", p2)


    // 假数据
    // int和float64都当float64
    b3 := []byte(`{"age":1.3,"name":"5lmh.com","marry":false}`)

    // 声明接口
    var i interface{}
    err3 := json.Unmarshal(b3, &i)
    if err3 != nil {
        fmt.Println(err3)
    }
    // 自动转到map
    fmt.Println(i)
    // 可以判断类型
    m := i.(map[string]interface{})
    for k, v := range m {
        switch vv := v.(type) {
        case float64:
            fmt.Println(k, "是float64类型", vv)
        case string:
            fmt.Println(k, "是string类型", vv)
        default:
            fmt.Println("其他")
        }
    }

    data, err := ioutil.ReadFile("./my.xml")
    if err != nil {
        fmt.Println(err)
        return
    }
    var servers Servers = Servers{}
    err = xml.Unmarshal(data, &servers)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("xml: %#v\n", servers)


    type Email struct {
		Where string `xml:"where,attr"`
		Addr  string
	}
	type Address struct {
		City, State string
	}
	type Result struct {
		XMLName xml.Name `xml:"Person"`
		Name    string   `xml:"FullName"`
		Phone   string
		Email   []Email
		Groups  []string `xml:"Group>Value"`
		Address
	}
	v := Result{Name: "none", Phone: "none"}

	data2 := `
		<Person>
			<FullName>Grace R. Emlin</FullName>
			<Company>Example Inc.</Company>
			<Email where="home">
				<Addr>gre@example.com</Addr>
			</Email>
			<Email where='work'>
				<Addr>gre@work.com</Addr>
			</Email>
			<Group>
				<Value>Friends</Value>
				<Value>Squash</Value>
			</Group>
			<City>Hanga Roa</City>
			<State>Easter Island</State>
		</Person>
	`
	err22 := xml.Unmarshal([]byte(data2), &v)
	if err22 != nil {
		fmt.Printf("error: %v", err22)
		return
	}
	fmt.Printf("XMLName: %#v\n", v.XMLName)
	fmt.Printf("Name: %q\n", v.Name)
	fmt.Printf("Phone: %q\n", v.Phone)
	fmt.Printf("Email: %v\n", v.Email)
	fmt.Printf("Groups: %v\n", v.Groups)
	fmt.Printf("Address: %v\n", v.Address)


    // err5 := writerJson("./person.dat")
    // if err5 != nil {
    //     fmt.Println(err5)
    //     return
    // }
    err4 := readJson("./person.dat")
    if err4 != nil {
        fmt.Println(err4)
        return
    }
}